package Service.SurroundService;

import Factory.ParamChangeUtil;
import Model.SurroundModel.Ship;
import Model.SurroundModel.Target;
import Service.ShipCalculate;

import java.util.ArrayList;
import java.util.List;

/**
 * 转换示例
 *
 * @author dingN
 * @date 2022/06/22
 */// 计算层实现实例
// TODO:  实现父类的Init方法，用于输入数据的初始化
// TODO： 实现父类的Calculate方法，未来所有的算法都只用来更改输入的几项数据的具体内容：目标队列，智能体小船队列，目标中心的，船队历史运行轨迹（可根据后续需求拓展）
// TODO:  实现父类的WorkingState方法，用来外部判断计算线程是否仍在工作
// TODO:  实现父类的ShutDown方法，用来结束运行
public class FirstOrderStaticTargetsService extends ShipCalculate{

    ParamChangeUtil paramChangeUtil = new ParamChangeUtil(); // 数据转换器

    public static String name = "一阶静态包围组件";

    static int SleepTime; // 计算休眠间隔
    static volatile boolean isWorking = false; // 是否运行

    // 计算实例，包含计算信息
    public Target target; // 目标队列
    public Ship ship; // 船队

    /**
     * 转换示例
     * @param sleepTime 睡眠时间
     */
    public FirstOrderStaticTargetsService(int sleepTime) {
        this.SleepTime = sleepTime;
        this.isWorking = true;
    }

    public void Init() {
        System.out.println(GetName() + "初始化了");
        this.initTarget();
        this.initShip();
        // 保存数据
        saveData(0);
    }

    public void Calculate() {
        this.calculate();
    }

    public boolean GetWorkingState() {
        return this.isWorking;
    }

    public void ShutDown(){
        this.isWorking = false;
    };

    public String GetName() {
        return name;
    }

    public void SetCalSpeed(int sleepTime){ this.SleepTime = sleepTime;};

    // 初始化目标信息
    public void initTarget() {
        target = new Target();
        target.initCircularPosition();
        target.setCenter();
    }

    // 初始化智能体
    public void initShip() {
        ship = new Ship();
        List<Ship> shipList = new ArrayList<>();
        shipList.add(new Ship(1, -5, 9));
        shipList.add(new Ship(2, 3, 4));
        shipList.add(new Ship(3, 7, 6));
        shipList.add(new Ship(4, 9, 4));
        ship.setPosition(shipList);

        //不断调整初始P值使得各个智能体对于目标估计中心位置初始值相同
        for (int i = 0; i < 50000; i++) {
            ship.setφ(0.00002);
            ship.setP(0.00002, target);
        }

//        // 保存数据
//        saveData(0);
    }

    /**
     * 保存数据
     * @param time 时间
     */
    public void saveData(double time) {
        //保存目标队列当前位置
        paramChangeUtil.SaveAllData(this, time);
    }


    // 计算并更新需要更新的数据
    public void calculate() {

        isWorking = true;

        double timeLength = 0.001;
        double count = 0;

        while (!ship.formationFinish(timeLength, target) && isWorking) {
            // 休眠
            try {
                Thread.sleep(SleepTime);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            //通过控制器去修改智能体对于目标的各项数值
            ship.formationController(timeLength, target);

            // 保存数据
            saveData(count);

            //时间跳到下一时刻
            count++;
        }

        isWorking = false;
    }
}
